#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <cstdlib>

const std::string op = "+-*/%";
int myMath(int x, int y, char op)
{
    int result = 0;
    switch (op)
    {
    case '+':
        result = x + y;
        break;
    case '-':
        result = x - y;
        break;
    case '*':
        result = x * y;
        break;
    case '/':
        if (y == 0)
        {
            std::cerr << "division 0 error" << std::endl;
            result = -1;
        }
        else
            result = x / y;
        break;
    case '%':
        if (y == 0)
        {
            std::cerr << "mod 0 error" << std::endl;
            result = -1;
        }
        else
            result = x % y;
        break;
    default:
        break;
    }

    return result;
}

class CalculateTask
{
    using func_t = std::function<int(int, int, char)>;

public:
    CalculateTask() {}
    CalculateTask(const int x, const int y, const char op, func_t func) : _x(x), _y(y), _op(op), _func(func)
    {
    }
    // int operator()()
    // {
    //     int result = _func(_x, _y, _op);
    //     return result;
    // }
    std::string operator()()
    {
        int result = _func(_x, _y, _op);
        char buffer[128];
        snprintf(buffer, sizeof(buffer) - 1, "%d %c %d = %d", _x, _op, _y, result);

        return buffer;
    }
    std::string toTaskString()
    {
        // 任务
        char buffer[128];
        snprintf(buffer, sizeof(buffer) - 1, "%d %c %d = ?", _x, _op, _y);
        return buffer;
    }
    ~CalculateTask()
    {}

private:
    int _x;
    int _y;
    char _op;
    func_t _func;
};

void Save(const std::string& msg)
{
    const std::string tarPath = "./log.txt";
    FILE* fp = fopen(tarPath.c_str(), "a+");
    if(!fp)
    {
        std::cerr << "fopen error" << std::endl;
        return;
    }

    fputs(msg.c_str(), fp);
    fputs("\n", fp);

    fclose(fp);
}
class SaveTask
{
    using func_t = std::function<void(const std::string&)>;
public:
    SaveTask(){}
    SaveTask(const std::string& msg1, const std::string msg2, func_t func = Save): _msg(msg1), __msg(msg2), _func(func)
    {}

    void operator()() const
    {
        _func(_msg);
    }
    const std::string& get_task_name() const
    {
        return __msg;
    }

    ~SaveTask()
    {}
private:
    std::string _msg;
    std::string __msg;
    func_t _func;
};
